/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						       hero_keyword_replacer.cpp

	$Header: /game/hero_keyword_replacer.cpp $

	$NoKeywords: $

 ************************************************************************/

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "hero_keyword_replacer.h"
#include "game_replace_keywords.h"

#include "creature.h"
#include "creature_array.h"
#include "creature_traits.h"
#include "creature_type.h"
#include "external_string.h"
#include "hero.h"
#include "format_string.h"
#include "material_names.h"
#include "replace_keywords.h"
#include "skill_properties.h"
#include "spell_properties.h"
// ------------------------------------------------------------------------
// class which replaces keywords with text
// ------------------------------------------------------------------------
extern t_external_string const k_text_and;

void t_hero_keyword_replacer::add_hero( t_hero const* hero )
{
	m_hero_count++;
	m_map["%hero_name"]  = hero->get_name();
	m_map["%hero_level"] = format_string( "%i", hero->get_level() );
	m_map["%hero_class"] = hero->get_class_name();
	m_map["%he"]		 = hero->get_pronoun();
	m_map["%him"]        = hero->get_accusative_pronoun();
	m_map["%his"]		 = hero->get_possessive_pronoun();
	m_map["%himself"]	 = hero->get_reflexive_pronoun();

	add_to_list( "%hero_names", m_hero_count, hero->get_name() );
}

// ------------------------------------------------------------------------
// class which replaces keywords with text
// ------------------------------------------------------------------------
void t_hero_keyword_replacer::add_heroes( std::vector<t_hero*> const& heroes )
{
	int i;

	for (i = heroes.size() - 1; i >= 0; i--)
		add_hero( heroes[i] );
}

// ------------------------------------------------------------------------
// class which replaces keywords with text
// ------------------------------------------------------------------------
void t_hero_keyword_replacer::add_creatures( t_creature_array const& creatures, bool approximate )
{
	int i;

	i = t_creature_array::k_size;
	while (i--)
	{
		if (creatures[i].get_number() > 0)
		{
			t_creature const * creature = creatures[i].get_creature();
			if ( creature )
			{
				add_creature( creature->get_number(),
							  creature->get_creature_type(), approximate );
			}
			else 
			{
				t_hero const * hero = creatures[i].get_hero();

				assert( hero ); // Has to be one of the two!

				add_hero_to_creature_list( hero->get_name() );
			}
		}
	}
}

// ------------------------------------------------------------------------
// class which replaces keywords with text
// add keywords for a hero's abilities with a spell
// ------------------------------------------------------------------------
t_external_string const k_text_creature( "creature.hero" );
t_external_string const k_text_creatures( "creatures.hero" );
t_external_string const k_text_life( "life.hero" );
t_external_string const k_text_lives( "lives.hero" );

void t_hero_keyword_replacer::add_spell( t_abstract_creature const* creature,
										 t_spell spell,
										 t_abstract_grail_data_source const & grail_data,
										 t_artifact const* artifact )
{
	int				power;
	std::string		power_string;
	t_creature_type summoned_creature = get_summoned_creature( spell );

	power = creature->get_spell_power( spell, grail_data );
	power_string = format_string( "%i", power );
	add_keyword( "%power", power_string );
	if (is_summoning( spell ) && summoned_creature != k_creature_none)
	{
		std::string creature_text = get_creature_name( summoned_creature, power, false );

		creature_text = power_string + " " + creature_text;
		add_keyword( "%creatures", creature_text );
	}
	else if (power == 1)
		add_keyword( "%creatures", "1 " + k_text_creature.get() );
	else
		add_keyword( "%creatures", power_string + " " + k_text_creatures.get() );
	if (power == 1)
		add_keyword( "%lives", "1 " + k_text_life.get() );
	else
		add_keyword( "%lives", power_string + " " + k_text_lives.get() );
	add_spell( creature, spell, artifact );
}

void t_hero_keyword_replacer::add_spell( t_abstract_creature const* creature, t_spell spell,
										 t_artifact const* artifact )
{
	t_hero const*	hero = dynamic_cast<t_hero const*>( creature );
	std::string		spell_name = ( artifact != 0 ? artifact->get_name() : get_spell_name( spell ) );

	if (hero != 0)
		add_hero( hero );
	add_keyword( "%spell_name", spell_name );
	++m_spell_count;
	add_to_list( "%spell_list", m_spell_count, spell_name );
}

void t_hero_keyword_replacer::add_skill( t_skill const& skill )
{
	std::string name = get_name( skill );

	add_keyword( "%skill_name", name );
	++m_skill_count;
	add_to_list( "%skill_list", m_skill_count, name );
}

// ------------------------------------------------------------------------
// class which replaces keywords with text
// add an artifact
// ------------------------------------------------------------------------
void t_hero_keyword_replacer::add_artifact( t_artifact const& artifact )
{
	t_map::iterator item;

	m_map["%artifact"] = artifact.get_name( false );
	m_map["%an_artifact"] = artifact.get_name( true );
	m_artifact_count++;
	add_to_list( "%artifact_list", m_artifact_count, artifact.get_name( true ));
	add_to_list( "%reward_list", m_material_count + m_artifact_count, artifact.get_name( true ));
}

// ------------------------------------------------------------------------
// class which replaces keywords with text
// add a list of artifacts
// ------------------------------------------------------------------------
void t_hero_keyword_replacer::add_artifacts( t_artifact_list const& artifacts )
{
	int i;

	for (i = artifacts.size() - 1; i >= 0; i--)
		add_artifact( artifacts[i] );
}

// ------------------------------------------------------------------------
// class which replaces keywords with text
// add a material
// ------------------------------------------------------------------------
void t_hero_keyword_replacer::add_material( int amount, t_material material )
{
	t_keyword_replacer::add_material( amount, material );
	add_to_list( "%reward_list", m_material_count + m_artifact_count,
		         format_string( "%i ", amount ) + get_material_name( material ));
}

// ------------------------------------------------------------------------
// replace keywords
// ------------------------------------------------------------------------
std::string replace_keywords( std::string const& format_string, t_hero const* hero )
{
	t_hero_keyword_replacer replacer;

	replacer.add_hero( hero );
	return replacer( format_string );
}

// ------------------------------------------------------------------------
// replace keywords
// ------------------------------------------------------------------------
std::string replace_keywords( std::string const& format_string, 
							  std::vector<t_hero*> const& heroes )
{
	t_hero_keyword_replacer replacer;

	replacer.add_heroes( heroes );
	return replacer( format_string );
}

// ------------------------------------------------------------------------
// replace keywords
// ------------------------------------------------------------------------
std::string replace_keywords( std::string const& text, t_abstract_creature const* creature,
							  t_spell spell, t_abstract_grail_data_source const & grail_data,
							  t_artifact const* artifact )
{
	t_hero_keyword_replacer replacer;

	replacer.add_spell( creature, spell, grail_data, artifact );
	return replacer( text );
}

std::string replace_keywords( std::string const& text, t_artifact const& artifact )
{
	t_hero_keyword_replacer replacer;

	replacer.add_artifact( artifact );
	return replacer( text );
}
